package org.feng.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.feng.api.DateRange;
import org.feng.api.OrderByMode;
import org.feng.api.PageBean;
import org.feng.api.animal.constant.AnimalSexEnum;
import org.feng.api.animal.constant.AnimalTypeEnum;
import org.feng.api.animal.request.AddAndUpdateAnimalRequest;
import org.feng.api.animal.request.DeleteAnimalRequest;
import org.feng.api.animal.request.QueryAnimalRequest;
import org.feng.api.animal.response.AddAndUpdateAnimalDto;
import org.feng.api.animal.response.DeleteAnimalDto;
import org.feng.api.animal.response.QueryAnimalVo;
import org.feng.convert.AnimalConvert;
import org.feng.entity.Animal;
import org.feng.mapper.AnimalMapper;
import org.feng.service.IAnimalService;
import org.feng.util.PageUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Objects;

/**
 * 动物业务处理实现
 *
 * @author feng
 */
@Service
public class AnimalServiceImpl extends ServiceImpl<AnimalMapper, Animal> implements IAnimalService {

    @Override
    public DeleteAnimalDto delete(DeleteAnimalRequest request) {
        DeleteAnimalDto result = new DeleteAnimalDto();
        // 批量删除
        int batchIds = this.getBaseMapper().deleteBatchIds(request.getIds());
        result.setSuccess(batchIds > 0);
        return result;
    }

    @Override
    public AddAndUpdateAnimalDto saveOrUpdate(AddAndUpdateAnimalRequest request) {
        check(request);

        AddAndUpdateAnimalDto result = new AddAndUpdateAnimalDto();
        // 新增动物
        if (request.getId() == null) {
            if (!StringUtils.hasText(request.getName())) {
                throw new IllegalArgumentException("动物名称不能为空");
            }
            // 判断动物名称是否重复，不允许重复
            checkExistName(request.getName());

            Animal animal = AnimalConvert.convertToAnimal(request);
            int insert = this.getBaseMapper().insert(animal);
            result.setSuccess(insert > 0);
            return result;
        }

        // 根据ID判断动物是否存在
        checkExistId(request.getId());
        Animal animal = AnimalConvert.convertToAnimal(request);
        // 修改动物
        int update = this.getBaseMapper().updateById(animal);
        result.setSuccess(update > 0);
        return result;
    }

    @Override
    public PageBean<QueryAnimalVo> queryPages(QueryAnimalRequest request) {
        // 创建分页对象
        IPage<Animal> page = new Page<>(request.getPageNum(), request.getPageSize());
        // 组装查询语句
        LambdaQueryWrapper<Animal> queryWrapper = encapsulateQueryWrapper(request);

        // 分页查询
        IPage<Animal> animalPage = this.getBaseMapper().selectPage(page, queryWrapper);

        // 处理查询结果，映射为vo实例列表
        List<QueryAnimalVo> resultList = AnimalConvert.convertToQueryVos(animalPage.getRecords());
        return PageUtil.convertPage(animalPage, resultList);
    }


    /**
     * 组装查询语句
     *
     * @param request 查询请求体
     * @return wrapper
     */
    private LambdaQueryWrapper<Animal> encapsulateQueryWrapper(QueryAnimalRequest request) {
        LambdaQueryWrapper<Animal> queryWrapper = Wrappers.lambdaQuery();
        // 模糊查询名字
        queryWrapper.like(StringUtils.hasText(request.getName()), Animal::getName, String.format("%%%s%%", request.getName()));
        // 年龄精准匹配
        queryWrapper.eq(request.getAge() != null, Animal::getAge, request.getAge());
        // 动物类型精准匹配
        AnimalTypeEnum animalType = AnimalTypeEnum.getByCode(request.getAnimalTypeCode());
        queryWrapper.eq(animalType != null, Animal::getAnimalType, animalType);
        // 动物性别精准匹配
        AnimalSexEnum animalSex = AnimalSexEnum.getByCode(request.getAnimalSexCode());
        queryWrapper.eq(animalSex != null, Animal::getAnimalSex, animalSex);

        // 创建日期范围查询
        DateRange createDateRange = request.getCreateDateRange();
        if (Objects.nonNull(createDateRange)) {
            queryWrapper.between(Objects.nonNull(createDateRange.getStart()) && Objects.nonNull(createDateRange.getEnd()),
                    Animal::getCreateTime, createDateRange.startLocalDateTime(), createDateRange.endLocalDateTime());
        }

        // 更新日期查询
        DateRange updateDateRange = request.getUpdateDateRange();
        if (Objects.nonNull(updateDateRange)) {
            queryWrapper.between(Objects.nonNull(updateDateRange.getStart()) && Objects.nonNull(updateDateRange.getEnd()),
                    Animal::getUpdateTime, updateDateRange.startLocalDateTime(), updateDateRange.endLocalDateTime());
        }

        // 处理排序规则
        processOrderBy(queryWrapper, request.getOrderByMode());

        return queryWrapper;
    }

    private void processOrderBy(LambdaQueryWrapper<Animal> queryWrapper, QueryAnimalRequest.QueryAnimalRequestOrderByMode orderByMode) {
        if (Objects.nonNull(orderByMode)) {
            // 创建时间
            if (StringUtils.hasText(orderByMode.getCreateTime())) {
                if (OrderByMode.DESC.equals(orderByMode.getCreateTime())) {
                    queryWrapper.orderByDesc(Animal::getCreateTime);
                } else {
                    queryWrapper.orderByAsc(Animal::getCreateTime);
                }
            }

            // 更新时间
            if (StringUtils.hasText(orderByMode.getUpdateTime())) {
                if (OrderByMode.DESC.equals(orderByMode.getUpdateTime())) {
                    queryWrapper.orderByDesc(Animal::getUpdateTime);
                } else {
                    queryWrapper.orderByAsc(Animal::getUpdateTime);
                }
            }
        }
    }

    /**
     * 校验请求参数是否合法
     *
     * @param request 请求体
     */
    private void check(AddAndUpdateAnimalRequest request) {
    }

    /**
     * 校验当前ID对应的数据是否存在
     *
     * @param id ID
     */
    private void checkExistId(Long id) {
        if (!this.getBaseMapper().exists(Wrappers.<Animal>lambdaQuery().eq(Animal::getId, id))) {
            throw new IllegalArgumentException("对应动物ID=【" + id + "】不存在！");
        }
    }

    /**
     * 校验当前名称对应的数据是否存在
     *
     * @param name 名称
     */
    private void checkExistName(String name) {
        if (this.getBaseMapper().exists(Wrappers.<Animal>lambdaQuery().eq(Animal::getName, name))) {
            throw new IllegalArgumentException("对应动物名称【" + name + "】已经存在！");
        }
    }
}
